feat(synapse-core): add piece batcher with message-size addPieces limiter - #933
Open
hugomrdias wants to merge 2 commits into
Open
feat(synapse-core): add piece batcher with message-size addPieces limiter#933hugomrdias wants to merge 2 commits into
hugomrdias wants to merge 2 commits into
Conversation
…iter Park and pull immediately, then coalesce on-chain addPieces using Curio piece-size bounds and the Filecoin 64KiB message budget instead of a fixed 40-piece count.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
synapse-dev | 5a20671 | Commit Preview URL Branch Preview URL |
Aug 24 2026, 03:36 PM |
hugomrdias
force-pushed
the
hugomrdias/batching
branch
from
August 21, 2026 17:59
b441f38 to
41d1ddc
Compare
hugomrdias
marked this pull request as ready for review
August 21, 2026 18:00
Kubuxu
reviewed
Aug 24, 2026
| return { kind: 'createDataSetAndAddPieces', metadata: datasetMetadata, cdn, pieces } | ||
| } | ||
|
|
||
| function fits(pieces: LimiterPiece[]): boolean { |
Contributor
There was a problem hiding this comment.
I'm assuming for legacy datasets we are going to limit here.
Kubuxu
approved these changes
Aug 24, 2026
Kubuxu
left a comment
Contributor
There was a problem hiding this comment.
SGTM, although the TS async flows are not my strong suit
| pull: (input: PullInput) => Promise<PieceResult> | ||
| /** Already on this SP. Join the addPieces window only. */ | ||
| enqueue: (piece: EnqueuePiece) => Promise<PieceResult> | ||
| flush: () => Promise<FlushResult | undefined> |
There was a problem hiding this comment.
Could you add comments for flush and close to make their expected behavior a clearer?
The current comments say that both trigger a flush and that close() waits for parking, but they don't make it clear that flush() only submits pieces that are already in windowSlots.
BravoNatalie
approved these changes
Aug 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
createPieceBatcherto park/pull pieces immediately and coalesce on-chainaddPieces/createDataSetAndAddPieceswith a tumbling window.addPiecesFits) and Curio PieceCID size bounds (MIN_UPLOAD_SIZE/MAX_UPLOAD_SIZE).presignForCommit/pull/commit. One-shotupload()is unchanged.How it works
Park and pull run per piece, immediately. The tumbling window only batches the on-chain call:
addPieces(tx hash + status URL; callers poll if they need confirmation).createDataSetAndAddPieces(waits until the set exists, then caches it). Later windows useaddPieces.{ kind: 'delay', ms: 0 }starts the timer only once the window has a piece and noupload/pullis still parking. New parking restarts the delay, so concurrent operations coalesce despite size or provider-latency differences.ms: 0flushes on the next macrotask after parking settles.{ kind: 'limiter' }sits until the next piece does not fit, orflush/close.pending + incomingdoes not fit, the current window flushes and the incoming piece starts the next one. A piece that cannot sit in a batch alone is rejected.pullsigns extraData for that one piece so Curio canestimateGas. Flush signs a new extraData for the whole window.upload/pull). A failed flush rejects every slot withAddPiecesFlushError; retry withenqueue.onParked: runs after the piece is on this SP and before it joins the window. Throw to keep it out of the batch.Public interfaces
Import from
@filoz/synapse-core/sp(and errors from@filoz/synapse-core/errors).Limiter (also used by synapse-sdk
presignForCommit/pull/commit):Budget is
SIZE_CONSTANTS.MAX_ADD_PIECES_MESSAGE_SIZE(64 KiB minus overhead), estimated from encodedaddPiecescalldata with dummy extraData. PieceCID raw size must be within Curio'sMIN_UPLOAD_SIZE–MAX_UPLOAD_SIZE.MAX_ADD_PIECES_BATCH_SIZE(40) remains a fee-preview heuristic only.Examples
Existing data set — coalesced uploads
Create a data set on first flush
Mix upload and SP-to-SP pull
onParked, then retry a failed flush withenqueueLimiter-only wait (tests / explicit flush)
Test plan
pnpm run lint:fixfrompackages/synapse-corepnpm testfrompackages/synapse-core(857 passing)delay: 0waits for all in-flight parking and coalesces different-latency uploadspnpm testinpackages/synapse-sdk(storage message-size tests)upload()still acceptsFile/Uint8Array/ReadableStreamand flushes on close